<?php

namespace MyLogger\Handlers;

use MyLogger\Logger;
use MyLogger\Formatters\FormatterInterface;

class RotatingFileHandler extends StreamHandler
{
    protected $filename;
    protected $maxFiles;
    protected $dateFormat;

    public function __construct(
        string $filename,
        int $maxFiles = 5,
        int $level = Logger::DEBUG,
        FormatterInterface $formatter = null,
        int $filePermission = 0644
    ) {
        $this->filename = $filename;
        $this->maxFiles = $maxFiles;
        $this->dateFormat = 'Y-m-d';
        
        parent::__construct($this->getTimedFilename(), $level, $formatter, $filePermission);
    }

    protected function getTimedFilename(): string
    {
        $fileInfo = pathinfo($this->filename);
        $timedFilename = $fileInfo['filename'] . '-' . date($this->dateFormat);
        
        if (isset($fileInfo['extension'])) {
            $timedFilename .= '.' . $fileInfo['extension'];
        }
        
        return $fileInfo['dirname'] . '/' . $timedFilename;
    }

    public function handle(array $record): bool
    {
        $currentFile = $this->getTimedFilename();
        if ($currentFile !== $this->url) {
            $this->close();
            $this->openStream($currentFile);
            $this->url = $currentFile;
        }
        
        // 执行滚动清理
        $this->rotate();
        
        return parent::handle($record);
    }

    protected function rotate()
    {
        $filePattern = pathinfo($this->filename, PATHINFO_DIRNAME) . '/' .
                       pathinfo($this->filename, PATHINFO_FILENAME) . '-*';
        
        if (isset(pathinfo($this->filename)['extension'])) {
            $filePattern .= '.' . pathinfo($this->filename, PATHINFO_EXTENSION);
        }
        
        $logFiles = glob($filePattern);
        if ($logFiles === false) {
            return;
        }
        
        // 按时间排序（从旧到新）
        usort($logFiles, function ($a, $b) {
            return filemtime($a) - filemtime($b);
        });
        
        // 如果文件数量超过最大保留数，则删除旧文件
        if (count($logFiles) > $this->maxFiles) {
            $filesToRemove = array_slice($logFiles, 0, count($logFiles) - $this->maxFiles);
            foreach ($filesToRemove as $file) {
                if (is_writable($file)) {
                    unlink($file);
                }
            }
        }
    }
}